function cgm2 % check convergence of CGM for solving Ax=b % and compare different error measures in the process % clear all previous variables and plots clear * clf % pick exact solution % ic=1: b=ones % ic=2: b=random % ic=3: b=fourier series sol ic=3; % loop for increasing N for ie=1:3 % set parameters and define matrix A N=25*2^(ie-1); M=N; nm=N*M lambda=1; A=matrix(lambda,N,M); % define b if ic==1 sol=ones(nm,1); elseif ic==2 sol=rand(nm,1); elseif ic==3 sol=fourier(N,M)'; end; b=A*sol; start_error=norm(sol,2); fprintf('\n n = %i Initial Error = %e\n\n',nm, start_error) % use CGM to solve matrix equation ' v=cgm(A,b,sol,ie); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function v=fourier(NN,M) modes=100; a=1; b=1; k=b/(M+1); h=a/(NN+1); for n=1:modes a1=cos(3*n*pi/(4*a))-cos(n*pi/(4*a)); an(n)=-2*a1/(n*pi*sinh(n*pi*b/a)); end; for j=1:M y=j*k; for i=1:NN x=h*i; s=0; for n=1:modes s=s+an(n)*sinh(n*pi*y/a)*sin(n*pi*x/a); end; ll=(j-1)*NN+i; v(ll)=s; end; end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % subfunction for creating the matrix A function A=matrix(lambda,N,M) nm=N*M; % generate the diagonal elements D = sparse(1:nm,1:nm,2*(1+lambda^2)*ones(1,nm),nm,nm); % generate the subdiagonal elements SD = sparse(2:nm,1:nm-1,-ones(1,nm-1),nm,nm); for i=N+1:N:nm-1 SD(i,i-1)=0; end; % generate the sub-subdiagonal elements SSD=sparse(N+1:nm,1:nm-N,-lambda^2*ones(1,nm-N),nm,nm); % use symmetry of A to complete construction A=D+SD+SD'+SSD+SSD'; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % subfunction for the CGM function x=cgm(A,b,sol,ie) % set CGM parameters tol=0.0000001; nm=length(b); x=zeros(nm,1); tic % start iteration r=b-A*x; d=r; rr=dot(r,r); error=1; counter=0; err=1; while err>tol counter=counter+1; iter(counter)=counter; if counter==1 beta=0; else beta=rr/rr0; end; d=r+beta*d; q=A*d; alpha=rr/dot(d,q); x=x+alpha*d; r0=r; r=r-alpha*q; rr0=rr; rr=dot(r,r); error2(counter)=norm(alpha*d); error3(counter)=norm(r); error(counter)=norm(x-sol); err=error(counter); if counter>2 if (error2(counter)<1e-6) & (error2(counter-1)>1e-6) fprintf('\n Number of CGM Iterations = %i Error = %e Time = %e \n\n',counter,error2(counter),toc) end; end; end; % plot results % get(gcf) %set(gcf,'Position', [377 468 558 548]); %set(gcf,'Position', [1100 368 589 505]); plotsize(558, 548) subplot(3,1,ie) loglog(iter,error,'k') hold on loglog(iter,error2,'r') loglog(iter,error3,'b') % axes and legend used in plot ylabel('Error','FontSize',14,'FontWeight','bold') if ie==3 xlabel('Iteration Steps','FontSize',14,'FontWeight','bold') text(2,0.00001,'n = 10000','FontSize',14,'FontWeight','bold') elseif ie==1 legend(' Error',' Iteration Error',' Residual',1); text(2,0.00001,'n = 625','FontSize',14,'FontWeight','bold') say=['Solving Laplaces Equation Using the CGM']; title(say,'FontSize',14,'FontWeight','bold') elseif ie==2 text(2,0.00001,'n = 2500','FontSize',14,'FontWeight','bold') end; % have MATLAB use certain plot options (all are optional) grid on set(gca,'MinorGridLineStyle','none') axis([ 1 1000 0.00000001 100]) set(gca,'YTick',[0.00000001 0.000001 0.0001 0.01 1.0 100]) set(gca,'FontSize',14); set(findobj(gcf,'tag','legend'),'FontSize',14,'FontWeight','bold'); hold off %fprintf('\n Number of CGM Iterations = %i Error = %e \n\n',counter,error(counter)) %cond(full(A),2) % subfunction plotsize ' function plotsize(width,height) siz=get(0,'ScreenSize'); bottom=max(siz(4)-height-95,1); set(gcf,'Position', [2 bottom width height]);